//
//  ViewConfigSetting.swift
//  EasyCoding
//
//  Created by Fanxx on 2019/6/3.
//  Copyright © 2019 Fanxx. All rights reserved.
//

import UIKit

public struct ECViewConfigSetting<TargetType> {
    public var action:(TargetType) -> Void
    public init(action: @escaping (TargetType) -> Void) {
        self.action = action
    }
}
///所有需要设置样式的都可继承该协议
public protocol ECViewConfigSetable { }
extension EasyCoding where Base: ECViewConfigSetable {
    @discardableResult
    fileprivate func config(animated duration: TimeInterval, configs:[ECViewConfigSetting<Base>]) -> Self {
        if duration > 0 {
            UIView.animate(withDuration: duration) {
                configs.forEach({$0.action(self.base)})
            }
        }else{
            configs.forEach({$0.action(self.base)})
        }
        return self
    }
    @discardableResult
    public func config(animated: Bool = false,_ config:ECViewConfigSetting<Base>...) -> Self {
        return self.config(animated: animated ? 0.25 : 0, configs: config)
    }
    @discardableResult
    public func config(animated duration: TimeInterval,_ config:ECViewConfigSetting<Base>...) -> Self {
        return self.config(animated: duration, configs: config)
    }
}
extension EasyCoding where Base: UIView {
    @discardableResult
    public static func config(animated: Bool = false,_ config:ECViewConfigSetting<Base>...) -> ECNamespaceWrapper<Base> {
        return self.Base().easy.config(animated: animated ? 0.25 : 0, configs: config)
    }
    @discardableResult
    public static func config(animated duration: TimeInterval,_ config:ECViewConfigSetting<Base>...) -> ECNamespaceWrapper<Base> {
        return self.Base().easy.config(animated: duration, configs: config)
    }
}
extension EC.NamespaceArrayImplement where Element: UIView {
    @discardableResult
    fileprivate func config(animated duration: TimeInterval, configs:[ECViewConfigSetting<Element>]) -> Self {
        if duration > 0 {
            UIView.animate(withDuration: duration) {
                self.base.forEach { el in
                    configs.forEach({ $0.action(el) })
                }
            }
        }else{
            self.base.forEach { el in
                configs.forEach({ $0.action(el) })
            }
        }
        return self
    }
    @discardableResult
    public func config(animated: Bool = false,_ config:ECViewConfigSetting<Element>...) -> Self {
        return self.config(animated: animated ? 0.25 : 0, configs: config)
    }
    @discardableResult
    public func config(animated duration: TimeInterval,_ config:ECViewConfigSetting<Element>...) -> Self {
        return self.config(animated: duration, configs: config)
    }
}
///UIView默认可设置样式
extension UIView: ECViewConfigSetable { }
///UICollectionViewLayout默认可设置样式
extension UICollectionViewLayout: ECViewConfigSetable { }

extension ECViewConfigSetable {
    @discardableResult
    public func easy(_ configs:ECViewConfigSetting<Self>...) -> Self {
        return self.easy(configs: configs)
    }
    @discardableResult
    public func easy(configs:[ECViewConfigSetting<Self>]) -> Self {
        configs.forEach({$0.action(self)})
        return self
    }
}
extension ECViewConfigSetable where Self: ECEmptyInstantiable {
    public static func easy(_ configs:ECViewConfigSetting<Self>...) -> Self {
        return self.init().easy(configs: configs)
    }
    public static func easy(configs:[ECViewConfigSetting<Self>]) -> Self {
        return self.init().easy(configs: configs)
    }
}
extension ECViewConfigSetting {
    ///组合多个样式
    public static func sheet(_ configs:ECViewConfigSetting<TargetType>...) -> ECViewConfigSetting<TargetType> {
        return .init(action: { (target) in
            configs.forEach({ $0.action(target) })
        })
    }
    ///自定义
    public static func custom(_ action:@escaping (TargetType) -> Void) -> ECViewConfigSetting<TargetType> {
        return .init(action: action)
    }
}

///静态样式表
var ECStaticViewConfigSheets: [String:Any] = [:]
extension EasyCoding where Base: ECViewConfigSetable {
    ///设置静态样式
    public static func config(_ config:ECViewConfigSetting<Base>...) {
        let className = String(describing: type(of: Base.self))
        ECStaticViewConfigSheets[className] = config
    }
    ///加载静态样式
    public func loadStaticConfig() {
        let className = String(describing: type(of: Base.self))
        if let configs = ECStaticViewConfigSheets[className] as? [ECViewConfigSetting<Base>] {
            configs.forEach({ $0.action(self.base) })
        }
    }
}
#if EASY_SHORTCUT

extension ECViewConfigSetable where Self: UIView {
    @discardableResult
    public func config(animated: Bool = false,_ config:ECViewConfigSetting<Self>...) -> Self {
        return self.easy.config(animated:  animated ? 0.25 : 0, configs: config).base
    }
    @discardableResult
    public func config(animated duration: TimeInterval,_ config:ECViewConfigSetting<Self>...) -> Self {
        return self.easy.config(animated: duration, configs: config).base
    }
    @discardableResult
    public static func config(animated: Bool = false,_ config:ECViewConfigSetting<Self>...) -> Self {
        return Self().easy.config(animated:  animated ? 0.25 : 0, configs: config).base
    }
    @discardableResult
    public static func config(animated duration: TimeInterval,_ config:ECViewConfigSetting<Self>...) -> Self {
        return Self().easy.config(animated: duration, configs: config).base
    }
}
extension Array where Element: UIView {
    @discardableResult
    public func config(animated: Bool = false,_ config:ECViewConfigSetting<Element>...) -> Self {
        return self.easy.config(animated: animated ? 0.25 : 0, configs: config).base
    }
    @discardableResult
    public func config(animated duration: TimeInterval,_ config:ECViewConfigSetting<Element>...) -> Self {
        return self.easy.config(animated: duration, configs: config).base
    }
}

#endif
